import { Body, Controller, Post, UseGuards } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { isNullOrEmptyString } from 'src/common/string-helper'
import { getNowDayInChina } from 'src/common/time-helper'
import {
    GetDeviceRawDataRequest,
    GetDeviceRawDataResponse,
    GetDeviceStatusRequest,
    ParseRawDataRequest
} from 'src/dto/data-parser/data-parser.action'
import { DeviceStatusDTO } from 'src/dto/data-parser/data-parser.dto'
import { ResponseBaseWithArrayData, ResponseBaseWithData } from 'src/dto/response-base'
import { Semantic } from 'src/dto/semantic'
import { AuthGuard } from 'src/guards/auth.guards'
import { LocalFileCollectionService } from 'src/services/data-collection/local-file-collection.service'
import { NasFileCollectionService } from 'src/services/data-collection/nas-file-collection.service'
import { Protocol808Service } from 'src/services/protocol/protocol-808.service'

// 808协议消息类型定义
export const MessageDirection = {
    /** 上行 接收 */
    UP: 'Rx',
    /** 下行 发送 */
    DOWN: 'Tx'
}

// 808协议主要消息类型
export const MessageType = {
    /** 终端心跳 */
    HEARTBEAT: '0002',
    /** 位置信息汇报 */
    LOCATION: '0200',
    /** 数据上行透传 */
    DATA_UP_TRANSPARENT: '0900',
    /** 终端属性应答 */
    TERMINAL_PROPERTY_RESPONSE: '0107'
}

@Controller('data-parser')
export class DataParserController {
    constructor(
        private readonly localFileCollectionService: LocalFileCollectionService,
        private readonly protocol808Service: Protocol808Service,
        private readonly nasFileCollectionService: NasFileCollectionService,
        private readonly configService: ConfigService
    ) {}

    /** 获取设备状态 */
    @Post('device-status')
    @UseGuards(AuthGuard)
    async getDeviceStatus(@Body() request: GetDeviceStatusRequest): Promise<ResponseBaseWithData<DeviceStatusDTO>> {
        const deviceNumber = request.deviceNumber
        if (isNullOrEmptyString(deviceNumber)) {
            return {
                success: false,
                messageId: Semantic.dataParser.mustHaveDeviceNumber,
                data: null
            }
        }

        // const data = await this.localFileCollectionService.readData({
        //     deviceNumber,
        //     date: parseDate('2025-05-29 12:00:00'),
        //     // date: getNowDayInChina(),
        //     basePath: path.join(process.cwd(), 'device-raw-data')
        // })

        const remoteFilePath = this.configService.get<string>('remoteFilePath')

        if (isNullOrEmptyString(remoteFilePath)) {
            return {
                success: false,
                messageId: 'remoteFilePath is not set',
                data: null
            }
        }

        const data = await this.nasFileCollectionService.readData({
            deviceNumber,
            date: getNowDayInChina(),
            basePath: remoteFilePath
        })

        if (data.length === 0) {
            return {
                success: true,
                messageId: 'success',
                data: null
            }
        }

        // 支持多种消息类型的解析
        const businessData = this.protocol808Service.parseBatch(data, [
            MessageType.HEARTBEAT,
            MessageType.LOCATION,
            MessageType.TERMINAL_PROPERTY_RESPONSE,
            MessageType.DATA_UP_TRANSPARENT
        ])

        return {
            success: true,
            messageId: 'success',
            data: {
                iccid: businessData.iccid,
                overSpeedAlarm: businessData.overSpeedAlarm,
                lowPressureAlarm: businessData.lowPressureAlarm,
                isLocated: businessData.isLocated,
                latitude: businessData.latitude,
                longitude: businessData.longitude,
                height: businessData.height,
                speed: businessData.speed,
                direction: businessData.direction,
                locationTime: businessData.locationTime,
                communicationSignal: businessData.cellularSignal,
                satelliteSignal: businessData.satelliteSignal,
                wifiStations: businessData.wifiStations,
                lbsStations: businessData.lbsStations,
                satelliteData: businessData.satelliteData,
                fourGSatelliteData: businessData.fourGSatelliteData,
                voltage: businessData.voltage,
                receivedTime: businessData.receivedTime,

                signalTypeRange: null,
                /** 电流 */
                current: null,
                /** 电池温度 */
                batteryTemperature: null,
                /** 电芯数据 */
                cellData: null,
                // 定位类型
                locationType: null,
                // 网络类型
                networkType: null,
                // 定位模块异常
                locationModuleException: null,
                // 通信模块异常
                communicationModuleException: null,
                // 电池异常
                batteryException: null,
                // 速度异常
                speedException: null
            }
        }
    }

    /** 获取设备今日的所有原始数据 */
    @Post('device-raw-data')
    @UseGuards(AuthGuard)
    async getDeviceRawData(@Body() request: GetDeviceRawDataRequest): Promise<ResponseBaseWithArrayData<GetDeviceRawDataResponse>> {
        // const data = await this.localFileCollectionService.readData({
        //     deviceNumber: request.deviceNumber,
        //     date: parseDate('2025-05-29 12:00:00'),
        //     basePath: path.join(process.cwd(), 'device-raw-data')
        // })

        const remoteFilePath = this.configService.get<string>('remoteFilePath')

        if (isNullOrEmptyString(remoteFilePath)) {
            return {
                success: false,
                messageId: 'remoteFilePath is not set',
                data: []
            }
        }

        const data = await this.nasFileCollectionService.readData({
            deviceNumber: request.deviceNumber,
            date: getNowDayInChina(),
            basePath: remoteFilePath
        })

        // 过滤上行数据 + 转换格式 + 解析时间戳
        const processedData: Array<{ rawData: string; receivedTime: string; timestamp: number }> = []

        for (const item of data) {
            // 预先分割字符串，避免重复分割
            const spaceIndex = item.indexOf(' ')
            if (spaceIndex === -1) continue

            const timeStr = item.substring(0, spaceIndex)
            const remainingPart = item.substring(spaceIndex + 1)
            const nextSpaceIndex = remainingPart.indexOf(' ')

            if (nextSpaceIndex === -1) continue

            const direction = remainingPart.substring(0, nextSpaceIndex)

            // 只处理上行数据
            if (direction === MessageDirection.UP) {
                const formattedTime = this.protocol808Service.formatTime(timeStr)
                const timestamp = formattedTime ? formattedTime.valueOf() : 0
                const receivedTime = timestamp > 0 ? new Date(timestamp).toISOString() : ''

                processedData.push({
                    rawData: item,
                    receivedTime,
                    timestamp
                })
            }
        }

        // 基于时间戳排序（倒序）
        processedData.sort((a, b) => b.timestamp - a.timestamp)

        // 计算间隔时间（使用时间戳差值，单位：秒）
        const dataWithIntervalTime = processedData.map((item, index) => {
            if (index === processedData.length - 1) {
                return {
                    rawData: item.rawData,
                    receivedTime: item.receivedTime,
                    intervalTime: 0
                }
            }

            // 修复间隔时间计算：使用完整的时间戳差值
            const intervalTime = Math.round((item.timestamp - processedData[index + 1].timestamp) / 1000)

            return {
                rawData: item.rawData,
                receivedTime: item.receivedTime,
                intervalTime: Math.max(0, intervalTime) // 确保间隔时间不为负数
            }
        })

        return {
            success: true,
            messageId: 'success',
            data: dataWithIntervalTime
        }
    }

    // 根据传入的原始数据，解析出业务数据
    @Post('parse-raw-data')
    @UseGuards(AuthGuard)
    parseRawData(@Body() request: ParseRawDataRequest): ResponseBaseWithData<DeviceStatusDTO> {
        try {
            const businessData = this.protocol808Service.parseCore(request.rawData)
            return {
                success: true,
                messageId: 'success',
                data: {
                    iccid: businessData.iccid,
                    overSpeedAlarm: businessData.overSpeedAlarm,
                    lowPressureAlarm: businessData.lowPressureAlarm,
                    isLocated: businessData.isLocated,
                    latitude: businessData.latitude,
                    longitude: businessData.longitude,
                    height: businessData.height,
                    speed: businessData.speed,
                    direction: businessData.direction,
                    locationTime: businessData.locationTime,
                    communicationSignal: businessData.cellularSignal,
                    satelliteSignal: businessData.satelliteSignal,
                    wifiStations: businessData.wifiStations,
                    lbsStations: businessData.lbsStations,
                    satelliteData: businessData.satelliteData,
                    fourGSatelliteData: businessData.fourGSatelliteData,
                    voltage: businessData.voltage,
                    receivedTime: businessData.receivedTime,
                    signalTypeRange: null,
                    /** 电流 */
                    current: null,
                    /** 电池温度 */
                    batteryTemperature: null,
                    /** 电芯数据 */
                    cellData: null,
                    // 定位类型
                    locationType: null,
                    // 网络类型
                    networkType: null,
                    // 定位模块异常
                    locationModuleException: null,
                    // 通信模块异常
                    communicationModuleException: null,
                    // 电池异常
                    batteryException: null,
                    // 速度异常
                    speedException: null
                }
            }
        } catch (error) {
            return {
                success: false,
                messageId: 'error',
                data: null
            }
        }
    }
}
